package com.example.quickleave;

import static org.opencv.core.Core.FILLED;
import static org.opencv.imgproc.Imgproc.LINE_8;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.util.TypedValue;

import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;

public class ImageProcessor {
    public static final String TAG = "util";

    public static void draw(Bitmap bitmap, List<Bitmap> pics, boolean is_crop) {
        int i = 0;
        while (i < pics.size()) {
            Bitmap pic = is_crop ? customCropImage(pics.get(i), (float) 225 / 216) : pics.get(i);
            overlayBitmaps(bitmap, pic, i * 270 + 48, 1012, 225, 216);
            i += 1;
        }
    }

    public static void drawTextAtBitmap(Bitmap bitmap, String text, int x, int y, int color, int size) {
        Canvas canvas = new Canvas(bitmap);
        Paint localPaint = new Paint();
        localPaint.setColor(Color.rgb(color, color, color));
        localPaint.setTextSize(size);
        localPaint.setAntiAlias(true);
        localPaint.setTypeface(Typeface.DEFAULT);
        canvas.drawText(text, x, y, localPaint);
    }

    public static void drawTextAtBitmap(Bitmap bitmap, String text, int x, int y, int color, int size, int space) {
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setColor(Color.rgb(color, color, color));
        paint.setTextSize(size);
        paint.setAntiAlias(true);
        paint.setTypeface(Typeface.DEFAULT);
        for (int i = 0; i < text.length(); i++) {
            canvas.drawText(String.valueOf(text.charAt(i)), i * space + x, y, paint);
        }
    }

    public static void drop(Mat mat) {
        fillRect(mat, 441, 65, 290, 50, new Scalar(248.0D, 248.0D, 248.0D));
        fillRect(mat, 246, 237, 158, 62);
        fillRect(mat, 275, 484, 85, 45);
        fillRect(mat, 263, 554, 368, 37);
        fillRect(mat, 264, 621, 367, 36);
        fillRect(mat, 264, 686, 66, 40);
        fillRect(mat, 47, 831, 514, 44);
        fillRect(mat, 764, 1416, 342, 33);
        fillRect(mat, 766, 1750, 343, 34);
        fillRect(mat, 46, 1010, 228, 220);
        fillRect(mat, 316, 1010, 228, 220);
        fillRect(mat, 387, 1740, 156, 51);
    }

    public static void fillRect(Mat mat, int x, int y, int weight, int height) {
        Imgproc.rectangle(mat, new Point(x, y), new Point(x + weight, y + height), new Scalar(255, 255, 255), FILLED, LINE_8, 0);
    }

    public static void fillRect(Mat mat, int x, int y, int weight, int height, Scalar color) {
        Imgproc.rectangle(mat, new Point(x, y), new Point(x + weight, y + height), color, FILLED, LINE_8, 0);
    }

    public static Bitmap getBitmap(Context context, int id) {
        BitmapFactory.Options options = new BitmapFactory.Options();
        TypedValue value = new TypedValue();
        context.getResources().openRawResource(id, value);
        options.inTargetDensity = value.density;
        options.inScaled = false;
        options.inMutable = true;
        return BitmapFactory.decodeResource(context.getResources(), id, options);
    }

    public static Bitmap handle(Bitmap bitmap, String name, String type, String time_begin, int days, String reason, String time_pass, String instructor, List<Bitmap> pics, boolean is_crop) {
        Mat mat = new Mat();
        Utils.bitmapToMat(bitmap, mat);
        drop(mat);
        Utils.matToBitmap(mat, bitmap);
        bitmap = bitmap.copy(Bitmap.Config.RGB_565, true);
        try {
            informate(bitmap, name, type, time_begin, days, reason, time_pass, instructor);
            draw(bitmap, pics, is_crop);
            return bitmap;
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    public static void informate(Bitmap bitmap, String name, String type, String time_begin, int days, String reason, String time_pass, String instructor)
            throws ParseException {
        int begin_title = 445;
        switch (name.length()) {
            case 3:
            default:
                break;
            case 4:
                begin_title = 430;
                break;
            case 2:
                begin_title = 460;
        }
        drawTextAtBitmap(bitmap, name + "的请假", begin_title, 108, 84, 46, 48);
        drawTextAtBitmap(bitmap, name, 249, 284, 103, 49);
        drawTextAtBitmap(bitmap, type, 275, 521, 107, 40, 44);
        drawTextAtBitmap(bitmap, time_begin, 266, 587, 107, 42);
        @SuppressLint("SimpleDateFormat") SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(Objects.requireNonNull(ft.parse(time_begin)));
        calendar.add(Calendar.DATE, days);
        drawTextAtBitmap(bitmap, ft.format(calendar.getTime()), 266, 653, 107, 42);
        drawTextAtBitmap(bitmap, days + "天", 265, 720, 107, 42);
        drawTextAtBitmap(bitmap, reason, 50, 871, 107, 40, 43);
        drawTextAtBitmap(bitmap, time_begin, 764, 1446, 100, 35);
        drawTextAtBitmap(bitmap, time_pass, 764, 1780, 100, 35);
        drawTextAtBitmap(bitmap, instructor, 389, 1786, 57, 50);
    }

    public static void overlayBitmaps(Bitmap bitmap, Bitmap pic, int x, int y, int weight, int height) {
        Canvas canvas = new Canvas(bitmap);
        Rect rect = new Rect(x, y, x + weight, y + height);
        canvas.drawBitmap(pic, null, rect, null);
    }

    // 实现类似 android:scaleType="centerCrop" 的效果
    public static Bitmap customCropImage(Bitmap originalBitmap, float targetRatio) {
        // 获取原始图片的尺寸
        int originalWidth = originalBitmap.getWidth();
        int originalHeight = originalBitmap.getHeight();

        // 计算裁剪区域
        int cropWidth, cropHeight, cropX, cropY;
        float originalRatio = (float) originalWidth / (float) originalHeight;
        if (originalRatio > targetRatio) { // 如果原始图片比目标比例更宽
            cropHeight = originalHeight;
            cropWidth = (int) (cropHeight * targetRatio);
            cropX = (originalWidth - cropWidth) / 2;
            cropY = 0;
        } else { // 如果原始图片比目标比例更窄
            cropWidth = originalWidth;
            cropHeight = (int) (cropWidth / targetRatio);
            cropX = 0;
            cropY = (originalHeight - cropHeight) / 2;
        }

        // 裁剪图片
        return Bitmap.createBitmap(originalBitmap, cropX, cropY, cropWidth, cropHeight);
    }
}
